# -*- coding: utf-8 -*-

#    OriginDB
#    Copyright (C) 2010  Jason Power <power.jg@gmail.com>
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License along
#    with this program; if not, write to the Free Software Foundation, Inc.,
#    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.


from PyQt4.QtGui import *
from PyQt4 import QtCore

from math import atan, pi, sqrt, sin, cos

import openbabel

from bond import Bond


class BondHelper(QGraphicsItem):

	helperRadius = 40
	helperPointSize = 3
	helperBrush = QBrush(QColor(220, 205, 160))

	snapThresh = 10
	
	def __init__(self, startPos, typ, parent=None):
		self.selected = False

		self.startPos = startPos
		self.endPos = startPos

		self.typ = typ

		if typ == "single":
			self.bo = 1
		elif typ == "double":
			self.bo = 2
		elif typ == "triple":
			self.bo = 3
		elif typ == "wedge":
			self.bo = 2
		elif typ == "hash":
			self.bo = 2
		elif typ == "squiggle":
			self.bo = 2
		elif typ == "cistrans":
			self.bo = 2
		else:
			typ = "single"

		# in scene coords
		self.helperPoints = []
		for angle in [0, pi/6, pi/3, pi/2, 2*pi/3, 5*pi/6, pi, 7*pi/6, 4*pi/3, 3*pi/2, 5*pi/3, 11*pi/6]:
			self.helperPoints.append(self.startPos+QtCore.QPointF(cos(angle),sin(angle))*self.helperRadius)

		self.length = sqrt((self.startPos.x()-self.endPos.x())**2+(self.startPos.y()-self.endPos.y())**2)
		self.angle = 0

		QGraphicsItem.__init__(self, parent)

		self.computeGeometry()

	def changeEnd(self, pos):
		closest = 1000000
		minPoint = None
		for point in self.helperPoints:
			d = sqrt((point.x()-pos.x())**2+(point.y()-pos.y())**2)
			if d < closest:
				closest = d
				minPoint = point
		if closest < self.snapThresh:
			self.endPos = minPoint
		else:
			self.endPos = pos
		self.computeGeometry()
		self.update()
		return self.endPos

	def computeGeometry(self):

		self.length = sqrt((self.startPos.x()-self.endPos.x())**2+(self.startPos.y()-self.endPos.y())**2)
		
		self.setPos(self.startPos + (self.endPos-self.startPos)*.5)
		v = self.endPos-self.startPos
		if v.x() != 0:
			angle = atan(v.y() / v.x())
		elif v.y() > 0:
			angle = pi/2
		else:
			angle = -pi/2
		if v.x() < 0:
			angle += pi

		self.rotate(angle*180/pi - self.angle)
		self.angle = angle*180/pi

		self.prepareGeometryChange()

	def boundingRect(self):
		width = self.length - Bond.padding*2
		right = Bond.padding
		left = Bond.padding

		height = 4 + (self.bo-1)*Bond.padding

		bondRect = QtCore.QRectF(-width/2.0-left, -height/2.0, width+right+left, height)
		helperRect = QtCore.QRectF(-self.helperRadius, -self.helperRadius, self.helperRadius*2, self.helperRadius*2)

		return (bondRect | helperRect)

	def drawHelper(self, painter):
		oldBrush = painter.brush()
		oldPen = painter.pen()

		painter.setBrush(self.helperBrush)
		painter.setPen(QPen(QtCore.Qt.NoPen))

		for rad in [0, pi/6, pi/3, pi/2, 2*pi/3, 5*pi/6, pi, 7*pi/6, 4*pi/3, 3*pi/2, 5*pi/3, 11*pi/6]:
			angle = rad - pi/180*self.angle
			painter.drawEllipse(self.mapFromScene(self.startPos)+QtCore.QPointF(cos(angle),sin(angle))*self.helperRadius,
								self.helperPointSize, self.helperPointSize)

		painter.setPen(oldPen)
		painter.setBrush(oldBrush)

	def paint(self, painter, option, widget):
		painter.setRenderHint(QPainter.Antialiasing, True)
		self.drawHelper(painter)
		#print "drawing bond:", self.bond.GetIdx()

		if self.selected:
			painter.drawRect(self.boundingRect())

		painter.setPen(Bond.pen)

		order = self.bo

		startPadding = 0
		endPadding = 0

		startPos = QtCore.QPointF(-self.length/2.0, 0)
		endPos = QtCore.QPointF(self.length/2.0,0)
		pnorm = QtCore.QPointF(0, Bond.spacing)
		vn = QtCore.QPointF(1,0)

		if self.typ == "wedge":
			painter.setBrush(QBrush(QColor(0,0,0)))
			painter.drawPolygon(startPos+vn*startPadding, endPos+pnorm-vn*endPadding, endPos-pnorm-vn*endPadding)
		elif self.typ == "hash":
			v1 = startPos+vn*startPadding-(endPos+pnorm-vn*endPadding)
			v2 = startPos+vn*startPadding-(endPos-pnorm-vn*endPadding)
			painter.drawLine(endPos+pnorm-vn*endPadding, endPos-pnorm-vn*endPadding)
			painter.drawLine(endPos+pnorm-vn*endPadding+v1*.25, endPos-pnorm-vn*endPadding+v2*.25)
			painter.drawLine(endPos+pnorm-vn*endPadding+v1*.5, endPos-pnorm-vn*endPadding+v2*.5)
			painter.drawLine(endPos+pnorm-vn*endPadding+v1*.75, endPos-pnorm-vn*endPadding+v2*.75)
			painter.drawLine(endPos+pnorm-vn*endPadding+v1*.95, endPos-pnorm-vn*endPadding+v2*.95)
		elif order == 1:
			painter.drawLine(startPos+vn*startPadding, endPos-vn*endPadding)
		elif order == 2:
			painter.drawLine(startPos-pnorm*.5+vn*startPadding, endPos-pnorm*.5-vn*endPadding)
			painter.drawLine(startPos+pnorm*.5+vn*startPadding, endPos+pnorm*.5-vn*endPadding)
		elif order >= 3:
			painter.drawLine(startPos+vn*startPadding, endPos-vn*endPadding)
			painter.drawLine(startPos-pnorm+vn*startPadding, endPos-pnorm-vn*endPadding)
			painter.drawLine(startPos+pnorm+vn*startPadding, endPos+pnorm-vn*endPadding)